/*********************************** (C) COPYRIGHT ******************************
 * address: https://gitee.com/liuniansihuo/multitasks-os
 *
 * Change Logs:
 * Date			Author      	Notes
 * 2019-06-26	LiuHuo			first version
 *
*******************************************************************************/
#include "cpu.h"
#include "typedef.h"
#include "os_task_driver.h"


#define IWDG_ENABLE 0


#define     OS_IWDG_TIME_MAX    (26200)   //26.2s


void os_iwdg_reload(void)
{
#if IWDG_ENABLE
    IWDG_ReloadCounter();
#endif
}

void os_iwdg_init(u32 ms)
{
#if IWDG_ENABLE
    typedef struct
    {
        u32 Prescaler;
        u8  IWDG_Prescaler;
    } IWDG_Prescaler_S;

    if (ms > OS_IWDG_TIME_MAX)
        ms = OS_IWDG_TIME_MAX; //最大时间设置

    IWDG_Prescaler_S prer_tab[] =
    {
        {4, IWDG_Prescaler_4},
        {8, IWDG_Prescaler_8},
        {16, IWDG_Prescaler_16},
        {32, IWDG_Prescaler_32},
        {64, IWDG_Prescaler_64},
        {128, IWDG_Prescaler_128},
        {256, IWDG_Prescaler_256},
    };

    u32 ms_count = ms * 40;
    IWDG_Prescaler_S tmp = {.Prescaler = 0, .IWDG_Prescaler = 0};
    for (u8 index = 0; index < sizeof(prer_tab) / sizeof(IWDG_Prescaler_S); index++)
    {
        if ((0x1000 * prer_tab[index].Prescaler) > ms_count) //t*40 = per*(rlr+1)
        {
            tmp = prer_tab[index];
            break;
        }
    }

    IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
	while(IWDG_GetFlagStatus( IWDG_FLAG_PVU ));
    IWDG_SetPrescaler(tmp.IWDG_Prescaler);

	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
	while(IWDG_GetFlagStatus( IWDG_FLAG_RVU ));
    IWDG_SetReload((ms_count / tmp.Prescaler) - 1); /*between 0 and 0x0FFF*/

    IWDG_Enable();

#endif
}


void os_clock_init(void)
{
 	#define   NVIC_VectTab_OFFEST (0x00005000u)
	NVIC_SetVectorTable(NVIC_VectTab_FLASH, NVIC_VectTab_OFFEST);	//this must be first!!!
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);


	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,  ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,   ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP,   ENABLE);

}

